package edu.sjsu.cs.queryopt.dbms.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import edu.sjsu.cs.queryopt.dbms.dao.*;

import edu.sjsu.cs.queryopt.dbms.error.CommandException;

/**
 * CS 286 - Project Part 2 - Implements create index, delete index, list table
 * indexes commands, and evaluate access path for a select statement.
 *
 * @author Seungbeom Ma
 * @version 2012/Nov/6
 */
public class DBMS {

        private static final String defaultInFileName = "Commands.txt";
        private static final String defaultOutFileName = "Output.txt";
        private static final String defaultReadFileName = " ";
        public static boolean file = true;
       
        /**
         * My Query
         * **/
        private static final String CREATE = "CREATE";
        private static final String DROP = "DROP";
        private static final String LIST = "LIST";
        public static ArrayList <String> queryPod = new ArrayList<String>();
        //private static final static
        public static String filepath = "/Users/seungbeomma/Documents/workspace/CSE286";
        static boolean orderby = false;

        /**
         * QueryType: it will keeps type of query for each line
         * C = CREATE
         * D = DROP
         * L = LIST
         * **/
        public static ArrayList <String> QueryType = new ArrayList<String>();
       
        /**IndexAndTableName: it will keep the name of table and index
         * C = index name + table name
         * D = index file name
         * L = table name
         *
         * **/
        public static ArrayList<String> IndexAndTableName = new ArrayList<String>();
        /**
         * ColIDAndDirection: It will keep the Column ID and Direction for "C"
         *
         * */
        static Index i = new Index();
        static CalCard cc = new CalCard();
        static IndexList il = new IndexList();
        static Helper h = new Helper();
        static SelectHelper sh = new SelectHelper();
        static FilterFactor ff = new FilterFactor();
        static AccessTypeFour atf = new AccessTypeFour();
        static AccessTypeOne ato = new AccessTypeOne();
        static InnerOrOuterTable ioo = new InnerOrOuterTable();
        static ErrorChecking ec = new ErrorChecking();
        static Select sl = new Select();
        
        static Table tbb = new Table("name");
        static PlanTable pl = new PlanTable();
        static Predicate pd = new Predicate();
      //  static Select slf = new Select(pl, pd, tbb);

        
        
        
        static ArrayList<Index> listinDBMS = new ArrayList<Index>(); // use this to assinge the data then
        static Map<String, ArrayList<String>> listmap = new HashMap<String, ArrayList<String>>();
        static ArrayList<String> keys = new ArrayList<String>();
        
        /**
         * 
         * Last Part
         * **/
        public static ArrayList<String> PlanTable = new ArrayList<String>(); // contain call infor for plantabl
        public static Hashtable<Integer, ArrayList<String>> PDtable = new Hashtable <Integer, ArrayList<String>>();
        
        static WordCapsule wc = new WordCapsule();

        /**
         * Main method to run DBMS.
         * @param args
         * @throws FileNotFoundException
         */
        public static void main(String[] args) throws FileNotFoundException {
        	 	ArrayList <Index> save  = new ArrayList<Index>();
        	 	ArrayList <Table> tsave  = new ArrayList<Table>();
        	 	ArrayList <String> tablename = new ArrayList<String>();
        	 	ArrayList <String> rtablename = new ArrayList<String>();
        	 	ArrayList <String> tbname = new ArrayList<String>();
        	 	Hashtable <String, ArrayList<String>> dbtable = new Hashtable<String, ArrayList<String>>();
        	 	ArrayList<String> outputContainer = new ArrayList<String>(); // it is contain indexlist
        	 	Index printIndex = new Index();
                Scanner queryFile = null;
                Scanner listfile = null;
                Scanner tableFile = null;
                
                // my file for reading table
                Scanner readTableFile = null;
                int printnumber = 0;
       
                // Check if arguments are passed
                if (args.length > 0) {
                        try {
                                // Use the first argument as file name
                                queryFile = new Scanner(new File(args[0]));
                        } catch (FileNotFoundException e) {
                                System.out.println(args[0]
                                                + " file not found. Provide a valid filename.");
                                return;
                        }
                } else {
                        try {
                                // Use the default file as command input
                                queryFile = new Scanner(new File(defaultInFileName));
                               
                        } catch (FileNotFoundException e) {
                                System.out.println(defaultInFileName
                                                + " was not found. Provide a filename.");
                                return;
                        }
                }

                // Check the first line of the input file
                if (queryFile.hasNextLine()) {
                        String fileLine = queryFile.nextLine();
                       
                        // Set output file flag
                        if (fileLine.equalsIgnoreCase("TRUE"))
                                file = true;
                        else if (fileLine.equalsIgnoreCase("FALSE"))
                                file = false;
                        else {
                                System.out.println("Incorrect Query File Format.");
                                queryFile.close();
                                return;
                        }
                }

                // Set output stream if file flag is true
                if (file) {
                        System.setOut(new PrintStream(new File(defaultOutFileName)));
                }

                // Run each command in the file
                while (queryFile.hasNextLine()) {
                        String query = queryFile.nextLine();

                        String[] tokens = query.split(" ");
//                      System.out.println(tokens.length);
                        try {
                                // Throw an error if query line is empty
                                if (tokens.length == 0) {
                                        throw new CommandException("Enter your command.");
                                }

                                // TODO your code goes here
                                if(CheckQueryTYPE(tokens[0]) == 1)
                                {
                                       // System.out.println("CREATE QUERY");
                                        queryPod = MappingQueryCreate.MappingCREATEQuery(tokens);
                                        if(queryPod != null)
                                        {
                                                String nameOftable = ""; // File name: something.tab
                                                String nameOfResultFile = "";
                                                String EachLineInTable = "";// read table line by line
                                                ArrayList<Integer> valueandtype = new ArrayList<Integer>(); // Even number Col Type
                                           //     System.err.println("queryPod " + queryPod);                                                                                                                        // Odd number size of type
                                                	rtablename.add(queryPod.get(1) +queryPod.get(0) );
                                                tbname.add(queryPod.get(1) );
                                                nameOftable = Helper.ReadBuildTableName(queryPod);
                                                
                                                nameOfResultFile = Helper.WriteBuildTableName(queryPod);
                                                int totalNumberOfRowsInTheCol = 0;
                                             //   System.out.println("It is show time!!");
                                                readTableFile = new Scanner(new File(nameOftable));
                                                int linenumber = 1;
                                                int numberofcal = 0;
                                                if(readTableFile.equals(""))
                                                {
                                                        System.out.println("Error: We don't have" + nameOftable);
                                                        return;
                                                }
                                                while(readTableFile.hasNext())
                                                {
                                                        EachLineInTable = readTableFile.nextLine();
                                                    //    System.out.println(EachLineInTable);
                                                        if(linenumber == 1)
                                                        {// read the first line and get the each cols size and type of value (int or char)
                                                                valueandtype =  TableHelper.checkColTypeAndValue(EachLineInTable);
                                                                numberofcal = Helper.HowManyColInTable(EachLineInTable);
                                                              //  System.out.println("numberofcal " + numberofcal);
                                                         
                                                               
                                                        }
                                                        else if(linenumber == 2)
                                                        {// read the second line and get the how many rows do we have
                                                                totalNumberOfRowsInTheCol = TableHelper.checkValueForCol(EachLineInTable);
                                                                 printnumber = Integer.parseInt(EachLineInTable.trim());
//                                                              System.out.println("Total Number of rows are " +  totalNumberOfRowsInTheCol);
                                                        }
                                                        else
                                                        {// using valueandtype and and actual row of the table
                                                                // to check whether values are matching it or not.
                                                                // then using querypod to acs or dec the file
                                                                TableHelper.checkEachRowTypeAndValue(valueandtype, EachLineInTable );
                                                           
                                                                ArrayList <String>printing = CreateTable.Createtb(readTableFile,queryPod ,nameOftable,numberofcal, valueandtype);
                                                         
                                                                ArrayList <String> DefPod = Helper.GetDef(queryPod , 2 , (queryPod.size()-1));
//                                                              
                                                                
                                                           //     System.out.println("printing " + printing);
                                                                i.name = nameOfResultFile;
                                                                //
                                                          //      tbname.add(nameOfResultFile);
                                                                //
                                                                i.definitions =DefPod;
                                                                i.rowCount = printnumber;
                                                                
                                                                for(int a = 0 ; a < printing.size() ; a++)
                                                                {
                                                                        i.addRow(CreateTable.NewOrder.get(a), printing.get(a));
                                                                }
                                                             
                                                              
                                                                i.saveIndex();
                                                                i.rows.clear();
                                                                
                                                                printIndex.definitions = i.definitions;
                                                                printIndex.rowCount = i.rowCount;
                                                                printIndex.name = i.name;
                                                                
                                                                printIndex.rows = i.rows;
                                                                save.add(printIndex);                                                               
                                                                //System.out.println("Save "  + save);
                                                                break;
                                                               
                                                        }
//                                                    
                                                        linenumber++;
                                                       
                                                }
                                        }
                                        else
                                        {
                                                System.out.println("It is nnnnoooooot show time :(");
                                        }
                                       
                                       
                                }
                                else if(CheckQueryTYPE(tokens[0]) == 2)
                                {
                                       // System.out.println("DROP QUERY");
                                        if(tokens[1].equals(WordCapsule.QWC_INDEX))
                                        {
                                             //   System.out.println("tokens[2] " + tokens[2]);
                                        	if(tokens.length < 3){
                                        		System.err.println("DROP QUERY: need table name ");
                                               
                                        	}
                                        	else{
                                        		//System.err.println(tokens[2]);
                                        		 Helper.deletefile(tokens[2]);
                                        	}
                                        }
                                        else
                                        {
                                                System.err.println("DROP QUERY: This is not Right Drop Query ");
                                        }
                                       

                                      
                                }
                                else if(CheckQueryTYPE(tokens[0]) == 3)
                                {
                                        if(tokens[1].equals(WordCapsule.QWC_INDEX))
                                        {
                                        	if(tokens[2].charAt(0) == WordCapsule.QWC_PRE_TABLE)
                                        	{
//                                        		System.err.println("tbname " + tbname);
                                        		if(TableHelper.isInt( tokens[2].substring(1)))
                                        		{
                                        			ArrayList<String> listfilename = new ArrayList<String>(); 
                                        			//list  <-- place to store data
                                        			// printIndexList <- function to print
                                        			// dont forget to clear() !!!!!
                                        			File folder = new File(".");
                                        			// gets you the list of files at this folder
                                        			File[] listOfFiles = folder.listFiles();
                                        			// loop through each of the files looking for filenames that match
                                        			for(int i = 0; i < listOfFiles.length; i++){
                                        			    String filename = listOfFiles[i].getName();
//                                        			    System.out.println("tokens[2] " + tokens[2]);
                                        			    if(filename.startsWith(tokens[2]) && listOfFiles[i].getName().endsWith(WordCapsule.resultfiletype)){
                                        			      //  System.out.println("file name " + filename);
                                        			        listfilename.add(filename.substring(0, 4));
                                        			    }
                                        			}

                                        			//System.err.println("listfilename " + listfilename);
                                        			
                                        			 ArrayList<String> listdef = new ArrayList<String>();
                                                     
                                                    
                                                     String filename = "";
                                                     boolean counter = true ;
                                                     for(int listindex = 0 ; listindex < listfilename.size() ;listindex++ )
                                                     {
                                                             keys.add(listfilename.get(listindex));
                                                             filename = listfilename.get(listindex) + WordCapsule.resultfiletype;
//                                                             System.out.println("filename " + filename);
                                                             listfile = new Scanner(new File(filename));
                                                             while(listfile.hasNextLine())
                                                             {
                                                                      String querys = listfile.nextLine();
                                                                     if(counter == true)
                                                                     {
                                                                              String[] token = querys.split(" ");
                                                                             listdef = new ArrayList<String>(Arrays.asList(token));
                                                                             for(int i = listdef.size() ; i < 5 ; i++)
                                                                             {
                                                                                     listdef.add("-");
                                                                                    
                                                                             }
                                                                             counter = false;
                                                                     }                                                                                                                                      
                                                                    
                                                             }
                                                             listmap.put(keys.get(listindex), listdef);
                                                             
                                                             counter = true;
                                                    
                                                     }
//                                                     System.out.println("listmap " + listmap);
                                        			
                                        			
                                        			ArrayList<Index> collection = new ArrayList<Index>();
                                        			ArrayList<String> prefName = new ArrayList<String>();   
                                        			for(int let = 0 ; let < tablename.size(); let++)
                                        			{
                                        				if(tablename.get(let).contains(tokens[2]))
                                        				{
                                        					
                                        					prefName.add(tablename.get(let));
                                        				}
                                        			}
                                        		
                                        			for(int me = 0 ; me < prefName.size() ; me++)
                                        			{
                                        				for(int print = 0 ; print < save.size(); print++)
                                        				{
                                        					if(prefName.get(me).equals(save.get(print).name))
                                        					{
                                        						
                                        						collection.add(save.get(print));
                                        					}
                                        				}
                                        				
                                        				
                                        			}
                                        			printIndexLists();
//                                        			
//                                        			il.list =collection;
//                                        			il.printIndexList();                              		
                                      		
                                       			}
                                        		else
                                        		{
                                        			System.err.println("ERROR: DMBS Table name should consist number");
                                        		}
                                        	}
                                    
                                        }
                                        else
                                        {
                                        	System.err.println("ERROR: DMBS Index Should be next the LIST");
                                        }
                                }
                                else if(tokens[0].equalsIgnoreCase("select"))
                                {
//                                	System.out.println("Select");
                                	int PTindex = 0 ;
                                	//Add the QBlackNo
                                	DBMS.PlanTable.add("1");
                                	//checking about collection the query infor
                                	
                                	int querysize = tokens.length -1;
                                	ArrayList<String> frontColpod = new ArrayList<String>();
                                	//from
                                	ArrayList<String> tablepod = new ArrayList<String>();
                                	//where 
                                	ArrayList<String> conditionpod = new ArrayList<String>();
                                	// = < >
                                	ArrayList<String> orderbypod = new  ArrayList<String>();
                                	
                                	
                                	int index = 1;
                                	
                                	
                                	// First get the column name
                                	// it stop when it apprach "from"
                                	while(!tokens[index].equalsIgnoreCase("from") && index <querysize)
                                	{
	                                		
	                                		// In this stage we chage the table name from from isTablenAME Correct
	                                		// this is because cols name must be TX.1 
	                                		// Second , we also can use "*" intead of col name so we put everhting 
	                                		if( h.IsTableNameCorrect(tokens[index]) || tokens[index].charAt(0) == '*'){
	                                			// need to check table name form t1.1 not t1
	                                			frontColpod.add(tokens[index]);
	                                		}
	                                		else if(tokens[index].trim().equals(",".trim()))
	                                		{// it is "," (because we can have many cols
	                                		 // what a useless like me :(, just igrone it...
	                                		}
	                                		else{
	                                			// if there is something else error
	                                			System.out.println(tokens[index].trim() + " is not table name try again");
	                                			break;
	                                		}
	                                		index++;
		                             }
		                                	/**
		                                	 * Checking the if there is case [T1.1 , *] OR NOT
		                                	 * */
//		                                	if(!h.IsTableNameAndStarTogether(frontColpod))
//		                                	{
//		                                		System.out.println("This is not right col name");
//		                                		
//		                                	}
		                                	/***
		                                	 * From table name [, tablename]
		                                	 * */
//		                                	System.out.println("frontColpod " + frontColpod);
		                                	if(tokens[index].equalsIgnoreCase("FROM"))
		                                	{
		                                		index++;
		                                		while(tokens[index].trim().charAt(0) == 'T' || tokens[index].trim().charAt(0) == ','){
		                                		
//		                                		    System.out.println("tokens "  + tokens[index]);
		                                			if(!tokens[index].equalsIgnoreCase(",")){
		                                			tablepod.add(tokens[index]);
		                                			}
		                                			index++;
//		                                			System.out.println("index " + index);
//		                                			System.out.println("tokens " + tokens.length);
		                                			if(index == tokens.length)
		                                			{
		                                				break;
		                                			}
		                                		}
		
		                                	}
		                                   	else 
		                                	{
		                                		System.out.println("Missing From ");
		                                	}
		                                	
		                                	if(h.IsTableNameCorrectList(tablepod)== false){
		                                		
		                                		System.out.println("IsTableNameCorrectList " + tablepod + " is not table name");
		                                	}         
		                                	
//		                                	System.out.println("tablepod " + tablepod);
		                                	
		                                	/**
		                                	 * WHERE colume_id <Condidtion> {{and|or} column ID <consition>}
		                                	 * */
//		                                	
		                                	
		                                	if(index < tokens.length){
		                                		/**
		                                		 * CASE 1
		                                		 * SELECT LASTNAME,WORKDEPT
											       FROM CORPDATA.EMPLOYEE
											       WHERE SEX='F'
											       ORDER BY WORKDEPT
											       this case
											       
											       
											       or
											       
											       SELECT LASTNAME,WORKDEPT
											       FROM CORPDATA.EMPLOYEE
											       WHERE SEX='F'
											    
		                                		 * */
		                                		
		                                			ArrayList<String> AfterWhereToCheckOrderBy = sh.ArrayToArrayList(tokens);
		                                		
				                                	if(!AfterWhereToCheckOrderBy.contains("WHERE") && AfterWhereToCheckOrderBy.contains("ORDER"))
				                                	{/**
				                                		WHERE..ORDER BY.. CASE
				                                	*/ index++;
//				                                		System.out.println("WHERE ... ORDER BY.. CASE WITHOUT WHERE ");
//				                                		System.out.println("AfterWhereToCheckOrderBy " + AfterWhereToCheckOrderBy);
				                                		if(AfterWhereToCheckOrderBy.contains("ORDER")){

				                                		
				                                		
							                                		//System.out.println("WHERE " + tokens[--index]);
							                                		while(!tokens[index].equalsIgnoreCase("ORDER"))
							                                		{
							                                			
							                                			
							                                			if(!tokens[index].equals(","))							                                								                                			
							                                			{
							                                			conditionpod.add(tokens[index].trim());
							                                			}
							                                			index++;
							                                			if(index == tokens.length)
							                                			{
							                                				break;
							                                			}
							                                			
							                                		}
							                                		/**
							                                		 * I know this is really bad thing ... sorry my code no time
							                                		 * */
							                                		int tracking = 0;
							                                		while(tracking < AfterWhereToCheckOrderBy.size())
							                                		{
							                                			if(AfterWhereToCheckOrderBy.get(tracking).trim().equals("BY")){
							                                				break;
							                                			}
							                                			tracking++;
							                                		}
							                                		tracking++;
							                                		while(tracking <  AfterWhereToCheckOrderBy.size()){
							                                			orderbypod.add(AfterWhereToCheckOrderBy.get(tracking).trim());
							                                			tracking++;
							                                		}
				                                		}

			                                			outputContainer = sh.getIndexList();
			                                			if(orderbypod.size() != 0){
			                                				if(conditionpod.get(conditionpod.size()-1).trim().equals("D") ||conditionpod.get(conditionpod.size()-1).trim().equals("A") ){
			                                					conditionpod.remove(conditionpod.size()-1);
			                                					orderbypod.remove(orderbypod.size()-1);
			                                				}
			                                			}
//			                                			System.out.println("conditionpod " + conditionpod);
//			                                			System.out.println("frontColpod " + frontColpod);
//			                                			System.out.println("orderbypod " + orderbypod);
			                                			sh.AccessType(outputContainer, conditionpod, frontColpod);
			                                			if(orderbypod.size() == 0){
			                                				PlanTable.add("N");
			                                			}
			                                			else{
			                                				
			                                				String num = sh.FindIndexOrderBy(outputContainer , orderbypod, frontColpod);
			                                				System.out.println("String num " + num);
			                                				/**
			                                				 * Checking sort part. If we use index there is no reason to use sort
			                                				 * */
			                                				if(num.equalsIgnoreCase("i love my ex girl friend")){
			                                					PlanTable.add("N");
			                                				}
			                                				else{
			                                					PlanTable.add("Y");
			                                				}
			                                			}
			                                			cc.getTableCards(tablepod);
			                                			
			                                			/*
			                                			 * iT DOSEN;T HAVE WHERE NO MATCHING COL
			                                			 * */
			                                			PlanTable.set(2, "0");
//			                                			System.out.println("PlanTable 3: "+ PlanTable);
			                                			//TODO cal cardi and ff
			                                			
			                                			
			                                			
				                               
				                                		
				                                	}
				                             		else if(AfterWhereToCheckOrderBy.contains("WHERE")&&AfterWhereToCheckOrderBy.contains("ORDER")){
			                                			/**
			                                			SELECT T1.1 from T1 ORDER BY T1.1 
			                                		*/
			                                			
//			                                			System.out.println("SELECT T1.1 from T1 ORDER BY T1.1  CASE.");
			                                			for(int iiii = index + 1; iiii < tokens.length ; iiii++ )
			                                			{
			                                				
			                                				if(tokens[iiii].trim().equals("ORDER")){
			                                					
			                                					for(int order = iiii+2; order < tokens.length ; order++){
			                                						orderbypod.add(tokens[order]);
			                                					}
			                                					break;
			                                				}
			                                				conditionpod.add(tokens[iiii]);

			                                			}
			                                			outputContainer = sh.getIndexList();
//			                                			System.out.println("orderbypod " + orderbypod);
			                                			sh.AccessType(outputContainer, conditionpod, frontColpod);
			                                			if(orderbypod.size() == 0){
			                                				PlanTable.add("N");
			                                			}
			                                			else{
			                                				String num = sh.FindIndexOrderBy(outputContainer , orderbypod, frontColpod);
//			                                				System.out.println("String num " + num);
			                                				if(num.equalsIgnoreCase("i love my ex girl friend")){
			                                					PlanTable.add("N");
			                                				}
			                                				else{
			                                					PlanTable.add("Y");
			                                				}
			                                			}
			                                			cc.getTableCards(tablepod);
//			                                			System.out.println("PlanTable 2: "+ PlanTable);
			                                			//TODO cal cardi and ff
			                                			
			                                			break;
			                                			
			                                			
			                                			
			                                		}
				                                	else{
				                                		/**
				                                		 * SELECT * from T1 ORDER BY T1.1 case
				                                		 * */
//				                                		System.out.println("SELECT * or table from .... where ... case");
				                                		/** Done with SELECT T1.1 from T1 WHERE T1.3 IN ( 100 , 200 , 300 )
				                                		 * SELECT T1.1 from T1 WHERE T1.3 = 100
				                                		 * SELECT * from T1 WHERE T1.3 = 100
				                                		 * SELECT * from T1 WHERE T1.5 = 100
				                                		 * SELECT T1.1 from T1 WHERE T1.5 = 100
				                                		 * SELECT T1.1 , T1.2 from T1 WHERE T1.5 = 100
				                                		 * SELECT T1.1 , T1.2 from T1 WHERE T1.3 = 100
				                                		 * 
				                                		 * */
				                                		
				                                		//while(index < tokens.length){
//				                                		System.out.println(index +" "+ tokens.length);
				                                		for(int i = index +1 ; i < tokens.length ; i++){
				                                			
				                                			if(!(tokens[i].trim().equals("ORDER")) && !(tokens[i].trim().equals("BY"))){
				                                				if(!tokens[i].trim().equals(",")){
				                                				conditionpod.add(tokens[i].trim());
				                                				}
				                                			}
				                                		

				                                			
				                                			
				                                		}
//				                                		if(ec.IsAssginSameType(conditionpod) == false){
//				                                			break;
//				                                		}
			                                			outputContainer = sh.getIndexList();
			                                			/**
			                                			 * IN CASE with no index
			                                			 * */
//			                                			System.out.println("conditionpod " + conditionpod);
//			                                			System.out.println("PlanTable 1 BEFORE CC : "+ cc.prediTable);
			                                			cc.CountCalOne(outputContainer, conditionpod, frontColpod, tablepod);
			                                			
			                                			ato.AccessTypeOne(outputContainer, conditionpod, frontColpod);
			                                			
			                                			
			                                			
			                                			
			                                			                          
			                                			if(orderbypod.size() == 0){
			                                				//PlanTable.add("N");
			                                				orderby = false;
			                                			}
			                                			else{
			                                				//PlanTable.add("Y");
			                                				orderby = true;
			                                			}
			                                			if(orderby == true){
			                                				if(!DBMS.PlanTable.get(7).equals("Y") ||!DBMS.PlanTable.get(7).equals("N"))
			                                				{
			                                					String copy = DBMS.PlanTable.get(7);
			                                					DBMS.PlanTable.set(7, "Y");
			                                					if(DBMS.PlanTable.size() > 7){
			                                					DBMS.PlanTable.set(8, copy);
			                                					}
			                                					else{
			                                						DBMS.PlanTable.add(copy);
			                                					}
			                                					
			                                				}
			                                				else{
			                                					String copy = DBMS.PlanTable.get(7);
			                                					DBMS.PlanTable.set(7, "N");
			                                					if(DBMS.PlanTable.size() > 7){
			                                					DBMS.PlanTable.set(8, copy);
			                                					}
			                                					else{
			                                						DBMS.PlanTable.add(copy);
			                                					}
			                                					
			                                				}
			                                			}
//			                                			if(){
//			                                				
//			                                				
//			                                			}
//			                                			System.out.println("PlanTable b: "+ cc.prediTable);
//			                                  			if(orderbypod.size() == 0){
//			                                				PlanTable.add("N");
//			                                			}
//			                                			else{
//			                                				PlanTable.add("Y");
//			                                			}
			                                			
			                                			cc.getTableCards(tablepod);
//			                                			System.out.println("PlanTable a: "+ PlanTable);
			                                			
			                                			if(ato.IsJoinPredicate(conditionpod)){
//			                                				System.out.println("MORE THAN 1 IN PLANTABLE FIND IN OR OUT");
			                                				
			                                			ioo.InnerOrOuter(outputContainer, conditionpod, frontColpod, tablepod);
			                                			}
//			                                			boolean inlistchecker = false;
//			                                			for(int ii = 0 ;  ii < cc.prediTable.size() ; ii++){
//			                                				for(int iii = 0 ; iii < cc.prediTable.get(ii).size() ; iii++){
//			                                					if(cc.prediTable.get(ii).get(0).equals("I")){
//			                                						inlistchecker= true;
//			                                					}
//			                                				}
//			                                				
//			                                			}
//			                                		//	tablepod
//			                                			if(inlistchecker){
//			                                				DBMS.PlanTable.set(1, "N");
//			                                			}
//			                                			System.out.println("PlanTable 1: "+ PlanTable);
//			                                			System.out.println("preditable 1: "+ cc.prediTable);
			                                			
			                                			
			                                			
			                                			
			                                			/*for testing*/
			                                			
			                                			

			                                			
			                                			//TODO cal cardi and ff
			                                			
				                                			//index++;
				                                		//}
				                                
				                                	}
//				                                	System.out.println("PlanTable 1-1: "+ PlanTable);
//		                                			System.out.println("preditable 1-1: "+ cc.prediTable);
		                                	}
		                                	else{
//		                                		System.out.println("SELECT * from T1 case");
		                                		/**
		                                		 * Case SELECT * FROM T1 or SELECT Some col in the table from Table
		                                		 * */
		                                		if(tablepod.size() > 1)
		                                		{
		                                			System.err.println("ERROR can select more than one table");
		                                			break;
		                                		}

//		                                		if(sh.IsOrderBy(tablepod)){
//		                                		DBMS.PlanTable.add("Y  :  ORDERBY");
//		                                		}
//		                                		else{
		                                			
//		                                		}//ORDERBY
//		                                		sh.GetCardinality(frontColpod,tablepod,  conditionpod);
		                                		//TODO
		                                		// NEED TO DO TABLE 1CARDINAYL BY calling fucntion
		                                		outputContainer = sh.getIndexList();
	                                			/**
	                                			 * 
	                                			 * */

	                                			atf.AccessTypeFour(outputContainer, conditionpod, frontColpod);
	                                			
//	                                			cc.CountCalFour(outputContainer , conditionpod , frontColpod, tablepod);
//	                                			if(!frontColpod.get(0).trim().equals("*")){
//	                                			sh.FindIndexSelect(outputContainer , frontColpod);
//	                                			}
//	                                		
	                                			cc.getTableCards(tablepod);
		                                		System.out.println("PlanTable  4" + PlanTable);
		                                		
		                                		
		                                		
		                                	}
		                                	


		                                	
//		                                	System.out.println("frontColpod " + frontColpod );
//		                                	System.out.println("tablepod " + tablepod );
//		                                	System.out.println("conditionpod " + conditionpod );
//		                                	System.out.println("orderbypod " + orderbypod );
		                                	/**
		                                	 * Checking table names error 
		                                	 * orderpbypod and frontcolpod is containing 
		                                	 * tablename + col number
		                                	 * however, tablepod should contain the all col name
		                                	 * this part is checking the smiple errors.
		                                	 * */
		                                	if(conditionpod.size() != 0 && orderbypod.size() != 0)
		                                	{
				                                	if(sh.IsSelectColCorrent(tablepod, frontColpod) == false || 
				                                			sh.IsWhereTableValueCorrent(tablepod, conditionpod) == false ||
				                                					sh.IsSelectColCorrent(tablepod, orderbypod) == false)
				                                	{
				                                		System.err.println("Error Table name is miss matching it");
				                                		break;
				                                	}
                                			}
		                                	else if(conditionpod.size() != 0)
		                                	{
		                                		if(sh.IsSelectColCorrent(tablepod, frontColpod) == false || 
			                                			sh.IsWhereTableValueCorrent(tablepod, conditionpod) == false){
				                                	
				                                		System.err.println("Error Table name is miss matching it");
				                                		break;
				                                	
		                                			
		                                		}
		                                	}
		                                	if((conditionpod.size() == 0 && orderbypod.size() == 0))
		                                	{// something like SELECT * FROM TABLE
//		                                		DBMS.PlanTable.add("R : ACCESSTYPE : R Scan");// ACCESSTYPE
//		                                		DBMS.PlanTable.add("No Matching Col ");//MATCH COL
//		                                		DBMS.PlanTable.add("No Access Name ");// ACCESS NAME
//		                                		DBMS.PlanTable.add("No Index Only");// Indexonly
//		                                		DBMS.PlanTable.add("S : Sequentual prefetch ");//Prefetch
//		                                		if(sh.IsOrderBy(tablepod)){
//		                                		DBMS.PlanTable.add("Y  :  ORDERBY");
//		                                		}
//		                                		else{
//		                                			DBMS.PlanTable.add("N  : NO ORDERBY");
//		                                		}//ORDERBY
//		                                		sh.GetCardinality(frontColpod,tablepod,  conditionpod);
//		                                		//TODO
//		                                		// NEED TO DO TABLE 1CARDINAYL BY calling fucntion
//		                                		System.out.println("PlanTable  2" + PlanTable);
		                                	}
		                                	else{
		                                	/**
		                                	 * TODO:
		                                	 * First,  SINGLE TABLE Access
		                                	 * -> No Index : No predicate, Predicate
		                                	 * -> Have Index : No predicate, Predicate
		                                	 * */
		                                	/**
		                                	 * sh = selectHelper
		                                	 * */
		                                	/**
		                                	 * Read the table from the tablpod
		                                	 * tablepod = [T1 , T2]
		                                	 * 
		                                	 * 
		                                	 *
		                                	 *
		                                	 * Hashtable Key: table name like T1
		                                	 * ArrayList<String>: Infor in the each table after I read
		                                	 * */
//                        	
		                                	
		                                }  
		                                	
		                                	ec.IsAssginSameType(conditionpod);
                                			
		                                	
		                                	int ptsize = DBMS.PlanTable.size();
		                                	if(ptsize < 10){
		                                		while(DBMS.PlanTable.size() < 10){
		                                			DBMS.PlanTable.add(" ");
		                                		}
		                                		
		                                	}
		                                	
		                                	printTableIndexes();
		                                	printPlanTable(conditionpod);
//		                                	for(int last = 0 ; last<  cc.prediTable.size() ; last++){
//		                                	System.out.println("cc.prediTable cc.prediTable " + cc.prediTable);
		                                	if(ff.isTran(conditionpod)){
		                                		if( cc.prediTable.size() > 1){
		                                			ff.makeTran(conditionpod);
			                                		ff.fftran.set(1, cc.prediTable.get( cc.prediTable.size() -1).get(1));
			                                		ff.fftran.set(3, cc.prediTable.get( cc.prediTable.size() -1).get(3));
			                                		cc.prediTable.put((cc.prediTable.size()), ff.fftran);
			                                	}
		                                		
		                                	}
		                                		printPredicateTable();
		                                		

		                                	 listfile.close();
		                                	 cc.prediTable = new Hashtable <Integer, ArrayList<String>>();
		                                	 DBMS.PlanTable =  new ArrayList<String>();
		                                	 
		                                	
		                                	 
                                }
                                else
                                {
                                       
                                        System.err.println("ERROR: DBMS MISSING PART OF QUERY");
                                       
                                }
                               
                               

                        }

                        catch (CommandException ce) {
                                System.out.println("Error in the command: " + ce.getError());
                        }

                        catch (Exception ex) {
                                System.out.println("Unknown error occurred.");
                                ex.printStackTrace();
                        }

                }
//               System.err.println("done done done");
              Helper.deletefile2(); 
              
              queryFile.close();
               
        }
        
        private static ArrayList<String> GetDef(ArrayList<String> queryPod2, int j,
                        int k) {
                // TODO Auto-generated method stub
                return null;
        }
        public static void printIndexLists() throws IOException {
        	System.out.println("\n\nPrinting Index List...");
        	System.out.print("\nIndex Name   ");
        	
        

        	
        	for (int i = 0; i < 5; i++)
    			System.out.print("COL" + i + "  ");
    		
    		System.out.print("\n-------------");
    		for (int i = 0; i < 5; i++)
    			System.out.print("------");
    	//	FileInputStream fstrem = new FileInputStream(keys.get(0)+".idx");
    		Hashtable <String ,ArrayList<String>> ht = new Hashtable <String ,ArrayList<String>>();
    		ArrayList<String> tm = new ArrayList<String>();
    		
    		for(int index = 0 ; index < keys.size() ; index++){
    		BufferedReader br = new BufferedReader(new FileReader(keys.get(index)+".idx"));
    			String line = br.readLine();
    			for(int inner = 0 ; inner < 1 ; inner++){
    				
    				String[] tokens = line.trim().split(" ");
    				for(int second = 0 ; second < tokens.length ; second++){
    					tm.add(tokens[second]);
    				}
    				
    			}
    			ht.put(keys.get(index), tm);
    			tm = new ArrayList<String>();
    		
    		
    		
    		}
//    		System.out.println("hthththt " + ht);
    		
        	for(int ii = 0 ; ii < keys.size(); ii++)
        	{
        		System.out.format("\n%-13s", keys.get(ii));
        		
        		for(int cool = 0 ; cool < ht.get(keys.get(ii)).size() ; cool++)
        		{
        			System.out.format("%-6s", ht.get(keys.get(ii)).get(cool));
        		}
        	}
        	
        	System.out.println("\n-----Writing-----");
        
        	
        	FileWriter writer = new FileWriter("output.txt"); 
        	for(int i = 0 ;  i < ht.size() ; i++){
        			writer.write(keys.get(i)+ " ");
		        	for(String str: ht.get(keys.get(i))) {
		        		if(!str.equals("-")){
		        			writer.write(str+ " ");
		        		}
		        		
		        	}
		        	writer.write('\n');
        	
        	}
        	writer.close();


        	
        }
        

        public static int CheckQueryTYPE(String partOfQuesyInCommandsFile)
        {

                return (partOfQuesyInCommandsFile.equals(CREATE)) ? 1 :
                                (partOfQuesyInCommandsFile.equals(DROP))? 2:
                                        (partOfQuesyInCommandsFile.equals(LIST))?3 :
                                                -9999;
               
        }
        public static List<String> textFiles(String directory) {
			  List<String> textFiless = new ArrayList<String>();
			  File dir = new File(directory);
			  for (File file : dir.listFiles()) {
			    if (file.getName().endsWith((".txt"))) {
			      textFiless.add(file.getName());
			    }
			  }
			  return textFiless;
			}
    	public static void printPlanTable(ArrayList<String> con) {
    		if(ato.IsJoinPredicate(con))
    		{
    			System.out.println("Plan Table \t\tValue");
        		System.out.println("--------------------------------");
        		System.out.println("QBlockNo \t\t" + DBMS.PlanTable.get(0));
        		if(cc.onlyor == false){
        		System.out.println("AccessType \t\t" + DBMS.PlanTable.get(1));
        		}
        		else
        		{
        			System.out.println("AccessType \t\t" + "N");
        		}
        		if(cc.onlyor == false){
        		System.out.println("MatchCols \t\t" + DBMS.PlanTable.get(2));
        		}
        		else{
        			System.out.println("MatchCols \t\t" + cc.orandor);
        		}
        		cc.onlyor = false;
        		System.out.println("AccessName \t\t" + DBMS.PlanTable.get(3));
        		System.out.println("IndexOnly \t\t" + DBMS.PlanTable.get(4));
        	
        		System.out.println("Prefetch \t\t" + DBMS.PlanTable.get(5));
        		
        		System.out.println("SortC_OrderBy \t\t" +DBMS.PlanTable.get(6));
        		System.out.println("Table1Card \t\t" + DBMS.PlanTable.get(7));
        		cc.orandor = 0;

//        		if (planTable.table2Card == 0)
        			
//        		else
        			System.out.println("Table2Card \t\t" +DBMS.PlanTable.get(8));

//        		if (planTable.leadTable != null)
        			System.out.println("LeadingTable \t\t" + DBMS.PlanTable.get(9));
//        		else
//        			System.out.println("LeadingTable \t\t ");

        		System.out.println();
    		}
//cc.orandor
    		else{
    		System.out.println("Plan Table \t\tValue");
    		System.out.println("--------------------------------");
    		System.out.println("QBlockNo \t\t" + DBMS.PlanTable.get(0));
    		if(cc.onlyor == false){
    		System.out.println("AccessType \t\t" + DBMS.PlanTable.get(1));
    		}
    		else
    		{
    			System.out.println("AccessType \t\t" + "N");
    		}
    		if(cc.onlyor == false){
    		System.out.println("MatchCols \t\t" + DBMS.PlanTable.get(2));
    		}
    		else{
    			System.out.println("MatchCols \t\t" + cc.orandor);
    		}
    		cc.onlyor = false;
    		System.out.println("AccessName \t\t" + DBMS.PlanTable.get(3));
    		System.out.println("IndexOnly \t\t" + DBMS.PlanTable.get(4));
    		if(DBMS.PlanTable.get(1).trim().equals("I")){
    			System.out.println("Prefetch \t\t" + " ");
    		}
    		else{
    		System.out.println("Prefetch \t\t" + DBMS.PlanTable.get(5));
    		}
    		System.out.println("SortC_OrderBy \t\t" +DBMS.PlanTable.get(6));
    		System.out.println("Table1Card \t\t" + DBMS.PlanTable.get(7));
    		cc.orandor = 0;

//    		if (planTable.table2Card == 0)
    			
//    		else
    			System.out.println("Table2Card \t\t" +DBMS.PlanTable.get(8));

//    		if (planTable.leadTable != null)
    			System.out.println("LeadingTable \t\t" + DBMS.PlanTable.get(9));
//    		else
//    			System.out.println("LeadingTable \t\t ");

    		System.out.println();
    		}

    	}
    	public static void printPredicateTable() {

    		System.out
    				.println("Predicate Table \tType \tC1 \tC2 \tFF1 \tFF2 \tSeq \tText \t\tDescription");
    		System.out
    				.println("----------------------------------------------------------------------------------------------------");
    		if(cc.fake.size() > 0){
    			cc.prediTable.put(0, cc.fake);
    			cc.fake = new ArrayList<String>();
    			cc.textPartForOr = "";
    			cc.stringOrExtra = "";
    		}
    		if(cc.prediTable.size() == 0){
    			
    		}
    		
//    		int i = 0;
    		else{
    			for(int index = 0 ; index < cc.prediTable.size() ; index++){
    		
//    			for(int inner = 0 ; inner < cc.prediTable.get(index).size() ; inner++){
    				String output ="PredNo" + (index+1) + "\t\t\t" + cc.prediTable.get(index).get(0) + "\t"
    						+ cc.prediTable.get(index).get(1) + "\t";
    				output += cc.prediTable.get(index).get(2);
    				output += "\t";
    				// 3 and 4
    				if(cc.prediTable.get(index).get(3).length() <6){
    				output +=cc.prediTable.get(index).get(3);//.substring(0, 5);
    				}
    				else{
    					output +=cc.prediTable.get(index).get(3).substring(0, 6);
    				}
    				output += "\t";
    				if(cc.prediTable.get(index).get(4).length() <6){
    					output +=cc.prediTable.get(index).get(4);
    				}
    				else{
    					output +=cc.prediTable.get(index).get(4).substring(0, 6);
    				}
    				output += "\t" + cc.prediTable.get(index).get(5) + "\t" +cc.prediTable.get(index).get(6);
    				if(cc.prediTable.get(index).size() > 7){
    					output +="\t\t" +cc.prediTable.get(index).get(7);
    				}	
    				
    				
    						System.out.println(output);
//    			}
    			
    			}
    		}

    	}
    	public static void printTableIndexes() throws IOException {
    		System.out.println("\nPrinting Select output ...\n");
        	System.out.print("\nIndex Name   ");       	
        	for (int i = 0; i < 5; i++)
    			System.out.print("COL" + i + "  ");
        	
        	System.out.print("HighKey\t\t");
			System.out.print("LowKey\t\t");
			System.out.print("\n-------------");
			for (int i = 0; i < 9; i++)
				System.out.print("------");
    		for(int index = 0 ; index < ato.keyofhtb.size() ; index++){
    			System.out.format("\n%-13s", ato.keyofhtb.get(index));
    			for (int inner = 0 ; inner < ato.htb.get(ato.keyofhtb.get(index)).size() ; inner++) {
					System.out.format("%-6s", ato.htb.get(ato.keyofhtb.get(index)).get(inner));
					
				}
    			System.out.print("\t");
    		System.out.println(cc.getHighKeyForIndex(ato.getTableNameFromIndex(ato.keyofhtb.get(index))));
    		System.out.println(cc.getLowKeyForIndex(ato.getTableNameFromIndex(ato.keyofhtb.get(index))));
    			
    		}
    		System.out.println();
    		ato.keyofhtb = new ArrayList<String>();
//    		Object tables;
//			for (Table table : tables) {
//    			System.out.println("Index table for " + table.name);
//    			int maxCols = 0;
//    			for (Index index : table.indexes) {
//    				if (maxCols < index.definitions.size())
//    					maxCols = index.definitions.size();
//    			}
//
//    			System.out.print("\nIndex Name   ");
//    			for (int i = 0; i < maxCols; i++)
//    				System.out.print("COL" + i + "  ");
//    			System.out.print("HighKey\t\t");
//    			System.out.print("LowKey\t\t");
//
//    			System.out.print("\n-------------");
//    			for (int i = 0; i < maxCols; i++)
//    				System.out.print("------");
//
//    			for (Index index : table.indexes) {
//    				System.out.format("\n%-13s", index.name);
//
//    				for (String definition : index.definitions) {
//    					System.out.format("%-6s", definition);
//    				}
//
//    				System.out.format("%-40s", index.highKey);
//    				System.out.format("%-40s", index.lowKey);
//    			}
//    			System.out.println();
//    		}
//
    	}
        
}

